require('dotenv').config();
const express = require('express');
const bodyParser = require('express').json;
const { v4: uuidv4 } = require('uuid');
const config = require('./config');
const { logger, childWithReqId } = require('./utils/logger');
const { openDatabase } = require('./db');
const { rateLimiter } = require('./middlewares/rateLimiter');
const { errorHandler } = require('./middlewares/errorHandler');
const path = require('path');

// Initialize DB at startup
openDatabase();

const app = express();
app.use(bodyParser());

// Request ID generation and structured request logging
app.use((req, res, next) => {
    const incomingId = req.headers['x-request-id'];
    const reqId = (typeof incomingId === 'string' && incomingId.trim()) || uuidv4();
    req.id = reqId;
    res.setHeader('x-request-id', reqId);
    const requestLogger = childWithReqId(reqId);
    res.locals.logger = requestLogger;

    const startTime = Date.now();
    requestLogger.info({ method: req.method, path: req.originalUrl }, 'request start');

    res.on('finish', () => {
        const durationMs = Date.now() - startTime;
        requestLogger.info({
            method: req.method,
            path: req.originalUrl,
            status: res.statusCode,
            durationMs,
            contentLength: res.getHeader('content-length'),
        }, 'request end');
    });

    next();
});

// Global rate limiter
app.use(rateLimiter);

// Routes
const downloadRoutes = require('./routes/downloadRoutes');
app.use('/api/downloads', downloadRoutes);

// Static frontend
const staticDir = path.resolve(__dirname, '../static');
app.use(express.static(staticDir));
app.get('/', (req, res) => {
    res.sendFile(path.join(staticDir, 'html', 'index.html'));
});

// Health
app.get('/health', (req, res) => res.json({ ok: true }));

// Error fallback
app.use(errorHandler);

const port = Number(process.env.PORT || config.PORT || 3000);
if (require.main === module) {
    app.listen(port, () => {
        logger.info({ port }, 'server started');
    });
}

module.exports = app;


